package ru.urfc.portal.managers;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;

import ru.urfc.portal.dao.RadioDao;
import ru.urfc.portal.dao.SpectrId;
import ru.urfc.portal.dao.filter.Filter;
import ru.urfc.portal.model.SpectrObject;
import ru.urfc.portal.model.radio.Device;
import ru.urfc.portal.model.radio.DeviceCertificate;
import ru.urfc.portal.model.radio.DeviceMeasurement;
import ru.urfc.portal.model.radio.DeviceSector;
import ru.urfc.portal.model.radio.DeviceStateChange;
import ru.urfc.portal.model.radio.DeviceWithExtra;
import ru.urfc.portal.model.radio.DeviceWithNet;
import ru.urfc.portal.model.radio.NetLicense;
import ru.urfc.portal.model.radio.NetWithLicense;
import ru.urfc.portal.operations.DeviceCertificatesFilter;
import ru.urfc.portal.operations.DeviceStateChangesFilter;

@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public class DeviceManager extends BaseManager {

	@EJB RadioDao radioDao;
	@EJB DeviceStateChangesFilter deviceStateChangesFilter;
	@EJB DeviceCertificatesFilter deviceCertificatesFilter;

	public List<DeviceWithNet> getDevices(Long clientId, Filter filter) {
		SpectrId contragentId = getContragentId(clientId);
		filter.addEqual("net.contragent.id", contragentId.getId());
		return wrapToDeviceWithNet(find(contragentId.getBranch(), Device.class, filter));
	}

	private List<DeviceWithNet> wrapToDeviceWithNet(List<Device> resultList) {
		List<DeviceWithNet> result = new ArrayList<DeviceWithNet>();
		for (Device item: resultList) {
			result.add(new DeviceWithNet(item, item.getNet()));
		}
		return result;
	}
	
	public DeviceWithExtra getDevice(Long clientId, Long deviceId) {
		return get(DeviceWithExtra.class, clientId, deviceId);
	}

	public NetWithLicense getDeviceNet(Long clientId, Long deviceId) {
		SpectrId contragentId = getContragentId(clientId);
		NetWithLicense net = getDevice(clientId, deviceId).getNet();
		NetLicense currentLicense = radioDao.getNetCurrentLicense(
				new SpectrId(net.getId(), contragentId), new Date());
		net.setCurrentLicense(currentLicense);
		return net;
	}

	protected <T extends SpectrObject> List<T> getDeviceDescendants(Class<T> descendantClass, Long clientId, Long deviceId) {
		SpectrId contragentId = getContragentId(clientId);
		getDevice(clientId, deviceId); // check
		return find(contragentId.getBranch(), descendantClass, "device.id", deviceId);
	}
	
	public List<DeviceSector> getDeviceSectors(Long clientId, Long deviceId) {
		return getDeviceDescendants(DeviceSector.class, clientId, deviceId);
	}

	public List<DeviceCertificate> getDeviceCertificates(Long clientId, Long deviceId) {
		DeviceWithExtra device = getDevice(clientId, deviceId);// check ids
		List<DeviceCertificate> certificates = find(DeviceCertificate.class, "deviceGuid", device.getGuid());
		return deviceCertificatesFilter.filter(certificates);
	}

	public List<DeviceMeasurement> getDeviceMeasurements(Long clientId, Long deviceId) {
		return getDeviceDescendants(DeviceMeasurement.class, clientId, deviceId);
	}

	public List<DeviceStateChange> getDeviceStateChanges(Long clientId, Long deviceId) {
		return deviceStateChangesFilter.filter(getDeviceDescendants(DeviceStateChange.class, clientId, deviceId));
	}

}
